package xcmg.device.service.boxup;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.PubMaterialsDO;
import xcmg.device.dao.entity.abnormal.AbnormalOutDetailDO;
import xcmg.device.dao.entity.barcode.BarcodeManageDO;
import xcmg.device.dao.entity.boxup.BoxupDetailDO;
import xcmg.device.dao.entity.boxup.BoxupMainDO;
import xcmg.device.dao.entity.boxup.DeliveryReceiptDetailDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDetailDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptLinkDO;
import xcmg.device.dao.entity.packageSpec.PackageSpecDO;
import xcmg.device.dao.entity.threeGuaranteesPur.ThreeGuaranteesOutDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryRecordDO;
import xcmg.device.dao.entity.warehouse.WarehouseInventoryDO;
import xcmg.device.dao.entity.warehouse.allot.RegionAllotDetailDO;
import xcmg.device.dao.mapper.BarcodeManageMapper;
import xcmg.device.dao.mapper.BoxupDetailMapper;
import xcmg.device.dao.mapper.BoxupMainMapper;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.DeliveryReceiptDetailMapper;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.PubMaterialsMapper;
import xcmg.device.dao.mapper.abnormal.AbnormalOutDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptLinkMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMapper;
import xcmg.device.dao.mapper.threeGuaranteesPur.ThreeGuaranteesOutDetailMapper;
import xcmg.device.dao.mapper.warehouse.RegionAllotDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryRecordMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInventoryMapper;
import xcmg.device.infra.BeanUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.StringUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.DeliveryReceiptEnum;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.packageSpec.PackageSpecService;
import xcmg.device.service.vo.boxup.BoxupDetailParam;
import xcmg.device.service.vo.boxup.BoxupDetailVO;
import xcmg.device.service.vo.boxup.BoxupIndexVO;
import xcmg.device.service.vo.boxup.BoxupMainVO;
import xcmg.device.service.vo.boxup.BoxupMaterialsQuery;
import xcmg.device.service.vo.boxup.BoxupParam;
import xcmg.device.service.vo.boxup.MaterialsDevanningParam;
import xcmg.device.service.vo.delivery.BoxUpDeliveryNoteVO;
import xcmg.device.service.vo.delivery.DeliveryNoteVO;
import xcmg.device.service.vo.delivery.PrintDeliveryReceiptDetailVO;
import xcmg.device.service.vo.delivery.PrintDeliveryReceiptVO;
import xcmg.device.service.vo.warehouse.WarehouseInventoryVO;
import xcmg.device.util.CompanyUtil;
import yb.ecp.fast.dto.UserCacheDTO;
import yb.ecp.fast.feign.AuthClient;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by sqq on 2018/2/26.
 */
@Service
public class BoxupMainService {

    @Autowired
    private BoxupMainMapper boxupMainMapper;

    @Autowired
    private BoxupDetailMapper boxupDetailMapper;

    @Autowired
    private FastGenClient fastGenClient;
    @Autowired
    private GenDocumentService genDocumentService;

    @Autowired
    private DeliveryReceiptMapper deliveryReceiptMapper;

    @Autowired
    private DeliveryReceiptLinkMapper deliveryReceiptLinkMapper;

    @Autowired
    private AuthClient authClient;

    @Autowired
    private DeliveryNoteDetailMapper deliveryNoteDetailMapper;

    @Autowired
    private WarehouseDeliveryRecordMapper warehouseDeliveryRecordMapper;

    @Autowired
    private DeliveryReceiptDetailMapper deliveryReceiptDetailMapper;

    @Autowired
    private ThreeGuaranteesOutDetailMapper threeGuaranteesOutDetailMapper;

    @Autowired
    private RegionAllotDetailMapper regionAllotDetailMapper;

    @Autowired
    private AbnormalOutDetailMapper abnormalOutDetailMapper;

    @Autowired
    private BarcodeManageMapper barcodeManageMapper;

    @Autowired
    private PackageSpecService packageSpecService;

    @Autowired
    private WarehouseInventoryMapper warehouseInventoryMapper;

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private CompanyUtil companyUtil;

    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private CompanyDealerMapper companyDealerMapper;

    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;

    @Autowired
    private PubMaterialsMapper pubMaterialsMapper;

    /**
     * 总条码
     */
    private static final String BARCODE_FLAG_WHOLE = "0";
    /**
     * 进出口SAP CODE
     */
    public static final String SAP_CODE = "4060";

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(BoxupParam boxupParam,String userId,String orgId,String userName) throws Exception{
        String deliveryReceiptNo = boxupParam.getDeliveryReceiptNo();
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(deliveryReceiptNo);
        if (deliveryReceiptDO == null) {
            return ErrorCode.DeliveryReceiptInfoNotExists;
        }
        if(deliveryReceiptDO.getCommitType().equals(1)){
            return ErrorCode.DeliveryReceiptCommited;
        }
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(deliveryReceiptDO.getId());
        if (deliveryReceiptLinkDOList == null || deliveryReceiptLinkDOList.size() <= 0) {
            return ErrorCode.DeliveryReceiptNDeliveryNote;
        }
        BoxupMainDO boxupMainDO = makeBoxupMainDO(boxupParam,userId,deliveryReceiptDO);
        if(boxupMainDO==null){
            return ErrorCode.IllegalArument;
        }

        if (CollectionUtils.isEmpty(boxupParam.getBarcodeList())){
            throw new Exception("装箱零件不能为空");
        }

        //判断是否混合装箱,否校验箱型 非混合装箱，扣减库存
        if (StringUtils.isEmpty(boxupParam.getBoxupNo())){
            PackageSpecDO packageSpecDO = null;
            //校验箱子的库存
            if (boxupMainDO.getPackageSpecId() != null) {
                packageSpecDO = packageSpecService.item(boxupMainDO.getPackageSpecId(), orgId);
                if (packageSpecDO.getQty() == null || packageSpecDO.getQty().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new Exception("包装箱数量不足！");
                }
            }

            // TODO: 2021/4/8  进出口对应的主机厂或者进出口自己有权限使用
            //进出口
            CompanyInfoDO companyInfoDO = companyInfoMapper.itemBySap(CompanyUtil.JCK_SAP_CODE);
            //进出口对应全部dealerOrgId
            List<String> dealerList = companyDealerMapper.findDealerOrgIds(companyInfoDO.getOrgId());
            dealerList = CollectionUtils.isEmpty(dealerList) ? Lists.newArrayList() : dealerList;
            dealerList.add(companyInfoDO.getOrgId());
            List<String> noDupList = dealerList.stream().distinct().collect(Collectors.toList());

            if (boxupMainDO.getPackageSpecId() != null && !companyInfoDO.getOrgId().equals(deliveryReceiptDO.getOrgId())
                    && !noDupList.contains(deliveryReceiptDO.getDealerOrgId())){
                throw new Exception("没有权限使用箱型");
            }

//            //减箱子库存
//            if (boxupMainDO.getPackageSpecId() != null) {
//                packageSpecService.updateInventoryQtyByPackageSpecId(boxupMainDO.getPackageSpecId());
//            }

            //箱子出库添加到出入库记录中
            ErrorCode recordCode = updateWarehouseRecord(packageSpecDO,boxupMainDO, orgId, userId, userName);
            if (recordCode.getCode() != ErrorCode.Success.getCode()){
                throw new Exception("箱子出库记录添加失败--" + recordCode.getDesc());
            }

            if (boxupMainMapper.insert(boxupMainDO) <= 0){
                throw new Exception("装箱失败");
            }

        }else{
            //更新原箱子重量
            BoxupMainDO orginMainDO = new BoxupMainDO();
            orginMainDO.setBoxupNo(boxupParam.getBoxupNo());
            orginMainDO.setRoughWeight(boxupParam.getRoughWeight()==null ? BigDecimal.ZERO : boxupParam.getRoughWeight());
            orginMainDO.setWeight(boxupParam.getWeight()==null ? BigDecimal.ZERO : boxupParam.getWeight());
            boxupMainMapper.updateByBoxupNo(orginMainDO);

            //检验是否为同一运单
            BoxupMainVO mainVO = new BoxupMainVO();
            mainVO.setBoxupNo(boxupParam.getBoxupNo());
            mainVO.setDeliveryReceiptNo(deliveryReceiptNo);
            List<BoxupMainDO> mainDOList = boxupMainMapper.list(mainVO);
            //同一运单无需新增
            if (CollectionUtils.isNotEmpty(mainDOList)){
                boxupMainDO.setBoxupId(mainDOList.get(0).getBoxupId());
            } else{
                if (boxupMainMapper.insert(boxupMainDO) <= 0){
                    throw new Exception("装箱失败");
                }
            }
        }

        for (BoxupDetailParam boxupDetailParam:boxupParam.getBarcodeList()) {
            packing(boxupDetailParam, deliveryReceiptLinkDOList,deliveryReceiptDO.getOrgId(), deliveryReceiptDO.getBillType(), boxupMainDO);
        }
        //修复一个bug岳丽丽提出http://10.90.1.198/zentao/bug-view-13294.html  add by wangzhaoyu
        //如果是发货通知单过来的装箱，需要更新T_WAREHOUSE_DELIVERY_RECORD的DELIVERY_RECEIPT_NO字段值为发运交接单的单号
        updateDeliveryRecode(deliveryReceiptLinkDOList,deliveryReceiptDO.getBillType());
        DeliveryReceiptDetailDO deliveryReceiptDetailDO=deliveryReceiptDetailMapper.item(deliveryReceiptDO.getId(),boxupParam.getPackCode());
        if(deliveryReceiptDetailDO==null){
            deliveryReceiptDetailDO=new DeliveryReceiptDetailDO();
            deliveryReceiptDetailDO.setDeliveryReceiptId(deliveryReceiptDO.getId());
            deliveryReceiptDetailDO.setDeliveryReceiptNo(deliveryReceiptDO.getBillNo());
            deliveryReceiptDetailDO.setPackCode(boxupParam.getPackCode());
            deliveryReceiptDetailDO.setPackDesc(boxupParam.getPackDesc());
            deliveryReceiptDetailDO.setDeliveryQty(BigDecimal.valueOf(1));
            deliveryReceiptDetailDO.setDeliveryWeight(boxupParam.getWeight());
            deliveryReceiptDetailMapper.insert(deliveryReceiptDetailDO);
        }else {
            BigDecimal deliveryWeight=BigDecimal.ZERO;
            deliveryReceiptDetailDO.setDeliveryQty(deliveryReceiptDetailDO.getDeliveryQty().add(BigDecimal.valueOf(1)));
            if(deliveryReceiptDetailDO.getDeliveryWeight()!=null && boxupParam.getWeight()!=null){
                deliveryWeight=deliveryReceiptDetailDO.getDeliveryWeight().add(boxupParam.getWeight());
            }else if(deliveryReceiptDetailDO.getDeliveryWeight()==null && boxupParam.getWeight()!=null){
                deliveryWeight=boxupParam.getWeight();
            }else if(deliveryReceiptDetailDO.getDeliveryWeight()!=null && boxupParam.getWeight()==null){
                deliveryWeight=deliveryReceiptDetailDO.getDeliveryWeight();
            }
            deliveryReceiptDetailDO.setDeliveryWeight(deliveryWeight);
            deliveryReceiptDetailMapper.update(deliveryReceiptDetailDO);
        }

        if (StringUtils.isNotEmpty(boxupParam.getBoxupNo())){
            //更新原交接单总重量
            if (updateOriginDeliveryWeight(boxupMainDO.getBoxupNo()) <= 0 ){
                throw new Exception("更新交接单总重量失败");
            }
        }

        return ErrorCode.Success;
    }

    private int updateOriginDeliveryWeight(String boxupNo){
        int num = 1;
        //查询箱号对应运单号
        List<BoxupMainDO> mainDOList = boxupMainMapper.listTotalWeight(boxupNo);
        if (CollectionUtils.isNotEmpty(mainDOList)){
            for (BoxupMainDO mainDO : mainDOList){
                DeliveryReceiptDetailDO detailDO = new DeliveryReceiptDetailDO();
                detailDO.setDeliveryReceiptNo(mainDO.getDeliveryReceiptNo());
                detailDO.setDeliveryWeight(mainDO.getWeight());
                num = deliveryReceiptDetailMapper.updateByDeliveryNo(detailDO);
                if (num <=0){
                    break;
                }
            }
        }
        return num;

    }

    private ErrorCode updateWarehouseRecord(PackageSpecDO packageSpecDO,BoxupMainDO boxupMainDO, String orgId, String userId, String userName) {
        LogHelper.monitor("pda装箱出库添加到出入库记录表，param:" + JSON.toJSONString(boxupMainDO));
        CompanyInfoDO companyInfoDO = companyInfoMapper.itemBySap(SAP_CODE);
        //判断如果是进出口的箱子，则添加到出入库记录中
        //根据sap code取orgId
        if (packageSpecDO != null && companyInfoDO != null) {
            if (!StringUtils.equals(companyInfoDO.getOrgId(),packageSpecDO.getOrgId())) {
                return ErrorCode.Success;
            }
        }else{
            return ErrorCode.Success;
        }

        //新增出库记录
        WarehouseDeliveryRecordDO warehouseDeliveryRecordDO = new WarehouseDeliveryRecordDO();
        warehouseDeliveryRecordDO.setId(fastGenClient.textGuid().getValue());
        //业务单号
        warehouseDeliveryRecordDO.setBusinessOrder(boxupMainDO.getDeliveryReceiptNo());
        //条形码 箱子是非条码入库的，此处填写装箱单号
        warehouseDeliveryRecordDO.setBarCode(boxupMainDO.getBoxupNo());
        //出入库类型
        warehouseDeliveryRecordDO.setBusinessSingle("XGZX");
        warehouseDeliveryRecordDO.setUnit("个");
        warehouseDeliveryRecordDO.setCreateDate(new Date());
        warehouseDeliveryRecordDO.setCreaterName(userName);
        warehouseDeliveryRecordDO.setCreaterId(userId);
        warehouseDeliveryRecordDO.setOrgId(packageSpecDO.getOrgId());
        //操作数量
        warehouseDeliveryRecordDO.setAmount(BigDecimal.ONE);
        if (StringUtils.isNotBlank(boxupMainDO.getPackageSpecId())) {
            //箱子零件编码
            warehouseDeliveryRecordDO.setMaterialNo(packageSpecDO.getMaterialsNo());
            //根据零件编码获取零件名称
            PriMaterialsDO priMaterialsDO = priMaterialsMapper.itemByNo(packageSpecDO.getMaterialsNo(), packageSpecDO.getOrgId());
            if (priMaterialsDO != null) {
                //箱子零件名称
                warehouseDeliveryRecordDO.setMaterialName(priMaterialsDO.getMaterialsDes());
            }

            WarehouseInventoryVO warehouseInventoryVO = new WarehouseInventoryVO();
            warehouseInventoryVO.setMaterialNo(packageSpecDO.getMaterialsNo());
            warehouseInventoryVO.setOrgId(packageSpecDO.getOrgId());
            warehouseInventoryVO.setIsOut(0);
            warehouseInventoryVO.setStatus(0);
            List<WarehouseInventoryDO> warehouseInventoryDOS = warehouseInventoryMapper.list(warehouseInventoryVO);
            BigDecimal amount = BigDecimal.ZERO;
            if (warehouseInventoryDOS != null && warehouseInventoryDOS.size() > 0) {
                for (WarehouseInventoryDO warehouseInventoryDO : warehouseInventoryDOS) {
                    amount = amount.add(warehouseInventoryDO.getAmount());
                }
                //获取箱子仓库编码
                warehouseDeliveryRecordDO.setWarehouseCode(warehouseInventoryDOS.get(0).getWarehouseCode());
                //设置库区
                warehouseDeliveryRecordDO.setAreaCode(warehouseInventoryDOS.get(0).getAreaCode());
                //设置储位
                warehouseDeliveryRecordDO.setLocationCode(warehouseInventoryDOS.get(0).getLocationCode());
            }

        }
        boolean success = warehouseDeliveryRecordMapper.insert(warehouseDeliveryRecordDO) > 0;
        return success ? ErrorCode.Success : ErrorCode.Failure;
    }

    //更新交运单对应的T_WAREHOUSE_DELIVERY_RECORD表中的DELIVERY_RECEIPT_NO字段
    private void updateDeliveryRecode(List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList,String billType) {
        if(CollectionUtils.isEmpty(deliveryReceiptLinkDOList)){
            return;
        }
        if(!StringUtils.isEmpty(billType)&& "XGFT".equals(billType)){
            for(DeliveryReceiptLinkDO link : deliveryReceiptLinkDOList){
                String deliveryBillNo = link.getDeliveryBillNo();
                String deliveryNoteNo = link.getDeliveryNoteNo();
                //从T_WAREHOUSE_DELIVERY_RECORD中根据business_order查询记录，如果存在记录且DELIVERY_RECEIPT_NO为空则进行更新操作
                warehouseDeliveryRecordMapper.updateReceiptNoWhereNull(deliveryNoteNo,deliveryBillNo);
            }
        }
    }


    /**
     * 继续装箱
     *
     * @param boxupId
     * @param barcode
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode keepPacking(String boxupId, String barcode, String orgId) throws Exception {
        BoxupMainDO boxupMainDO = boxupMainMapper.item(boxupId);
        BarcodeManageDO barcodeManageDO = barcodeManageMapper.item(barcode, orgId);

        if (!BARCODE_FLAG_WHOLE.equals(barcodeManageDO.getBarcodeFlag())) {
            keepPackingByBarcode(barcodeManageDO, boxupMainDO, orgId);
            return ErrorCode.Success;
        }
        List<BarcodeManageDO> barcodeManageDOList = barcodeManageMapper.findByTotalBarcode(barcode, orgId);
        for (BarcodeManageDO barcodeManage : barcodeManageDOList) {
            keepPackingByBarcode(barcodeManage, boxupMainDO, orgId);
        }
        return ErrorCode.Success;
    }

    /**
     * 条码装箱
     * @param barcodeManageDO
     * @param boxupMainDO
     * @param orgId
     * @throws Exception
     */
    private void keepPackingByBarcode(BarcodeManageDO barcodeManageDO, BoxupMainDO boxupMainDO, String orgId)
        throws Exception {
        BoxupDetailParam boxupDetailParam = new BoxupDetailParam();
        boxupDetailParam.setBarcode(barcodeManageDO.getBarcode());
        boxupDetailParam.setMateriatsNo(barcodeManageDO.getMaterialsNo());
        boxupDetailParam.setMateriatsDes(barcodeManageDO.getMaterialsDes());
        boxupDetailParam.setQty(barcodeManageDO.getCurrentQty());

        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.item(boxupMainDO.getDeliveryReceiptId());
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(boxupMainDO.getDeliveryReceiptId());

        packing(boxupDetailParam, deliveryReceiptLinkDOList,orgId, deliveryReceiptDO.getBillType(), boxupMainDO);

        //如果是发货通知单过来的装箱，需要更新T_WAREHOUSE_DELIVERY_RECORD的DELIVERY_RECEIPT_NO字段值为发运交接单的单号
        updateDeliveryRecode(deliveryReceiptLinkDOList, deliveryReceiptDO.getBillType());
    }


    @Transactional(rollbackFor = Exception.class)
    public void packing(BoxupDetailParam boxupDetailParam, List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList,
        String orgId, String billType, BoxupMainDO boxupMainDO)
        throws Exception {
        BoxupMaterialsQuery boxupMaterialsQuery=new BoxupMaterialsQuery();
        boxupMaterialsQuery.setMaterialsNo(boxupDetailParam.getMateriatsNo());
        boxupMaterialsQuery.setDeliveryReceiptLinkDOList(deliveryReceiptLinkDOList);

        boxupMaterialsQuery.setBarcode(boxupDetailParam.getBarcode());
        boxupMaterialsQuery.setOrgId(orgId);
        List<WarehouseDeliveryRecordDO> deliveryNoteNos=warehouseDeliveryRecordMapper.findBusinessOrder(boxupMaterialsQuery);
        if(ListUtil.isNullOrEmpty(deliveryNoteNos)){
            throw new Exception(boxupDetailParam.getBarcode()+",单据无此零件或该零件未出库");
        }
        BigDecimal sourQty=boxupDetailParam.getQty();
        for(WarehouseDeliveryRecordDO deliveryNoteNo : deliveryNoteNos){
            if(StringUtil.isNotEmpty(deliveryNoteNo.getDeliveryReceiptNo())){
                //如果一个条码出多行记录已实际单据对应数量为准
                if(sourQty.compareTo(deliveryNoteNo.getAmount())>0){
                    boxupDetailParam.setQty(deliveryNoteNo.getAmount());
                }
            }
            BoxUpDeliveryNoteVO boxUpDeliveryNoteVO=new BoxUpDeliveryNoteVO();
            switch (billType){
                case"XGFT":
                    boxUpDeliveryNoteVO=deliveryNoteDetailMapper.itemByNoAndMaterialsNo(orgId,deliveryNoteNo.getBusinessOrder(),boxupDetailParam.getMateriatsNo());
                    break;
                case "XGSC":
                    boxUpDeliveryNoteVO=threeGuaranteesOutDetailMapper.itemByNoAndMaterialsNo(orgId,deliveryNoteNo.getBusinessOrder(),boxupDetailParam.getMateriatsNo());
                    break;
                case "XGQD":boxUpDeliveryNoteVO=regionAllotDetailMapper.itemByNoAndMaterialsNo(orgId,deliveryNoteNo.getBusinessOrder(),boxupDetailParam.getMateriatsNo());
                    break;
                case "XGFC":
                    boxUpDeliveryNoteVO=abnormalOutDetailMapper.itemByNoAndMaterialsNo(orgId,deliveryNoteNo.getBusinessOrder(),boxupDetailParam.getMateriatsNo());
                    break;
            }
            //BoxUpDeliveryNoteVO boxUpDeliveryNoteVO=deliveryNoteDetailMapper.itemByNoAndMaterialsNo(boxupParam.getOrgId(),deliveryNoteNo,boxupDetailParam.getMateriatsNo());
            if(boxUpDeliveryNoteVO==null){
                throw new Exception("业务单据无此零件");
            }
            Integer barcodeCount=boxupDetailMapper.barcodeCount(boxupDetailParam.getBarcode(), boxUpDeliveryNoteVO.getDeliveryNoteId());
            if(barcodeCount>0){
                throw new Exception(boxupDetailParam.getBarcode()+"重复装箱");
            }
            BigDecimal paceNumberSum=boxUpDeliveryNoteVO.getPackNumber().add(boxupDetailParam.getQty());
            if(boxUpDeliveryNoteVO.getInventoryOutAmount().compareTo(paceNumberSum)<0){
                throw new Exception(boxupDetailParam.getBarcode()+"本次发货数量大于剩余数量,操作失败");
            }
            BoxupDetailDO boxupDetailDO=makeBoxupDetailDO(boxupMainDO,boxupDetailParam,boxUpDeliveryNoteVO);
            boxupDetailMapper.insert(boxupDetailDO);
            switch (billType){
                case"XGFT":
                    DeliveryNoteDetailDO deliveryNoteDetailDO=new DeliveryNoteDetailDO();
                    deliveryNoteDetailDO.setPackNumber(paceNumberSum);
                    deliveryNoteDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    deliveryNoteDetailMapper.update(deliveryNoteDetailDO);
                    break;
                case "XGSC":
                    ThreeGuaranteesOutDetailDO threeGuaranteesOutDetailDO=new ThreeGuaranteesOutDetailDO();
                    threeGuaranteesOutDetailDO.setPackNumber(paceNumberSum);
                    threeGuaranteesOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    threeGuaranteesOutDetailMapper.update(threeGuaranteesOutDetailDO);
                    break;
                case "XGQD":
                    RegionAllotDetailDO regionAllotDetailDO=new RegionAllotDetailDO();
                    regionAllotDetailDO.setPackNumber(paceNumberSum);
                    regionAllotDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    regionAllotDetailMapper.updateByPrimaryKeySelective(regionAllotDetailDO);
                    break;
                case "XGFC":
                    AbnormalOutDetailDO abnormalOutDetailDO=new AbnormalOutDetailDO();
                    abnormalOutDetailDO.setPackNumber(paceNumberSum);
                    abnormalOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    abnormalOutDetailDO.setStatus(null);
                    abnormalOutDetailMapper.updateByPrimaryKeySelective(abnormalOutDetailDO);
                    break;
            }
        }
    }



    @Transactional(rollbackFor = Exception.class)
    public ErrorCode materialsDevanning(MaterialsDevanningParam materialsDevanningParam) throws Exception{
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(materialsDevanningParam.getDeliveryReceiptNo());
        if (deliveryReceiptDO == null) {
            return ErrorCode.DeliveryReceiptInfoNotExists;
        }
        if(!deliveryReceiptDO.getDeliveryStatus().equals(DeliveryReceiptEnum.DeliveryStatus.UnDelivery.toString())){
            return ErrorCode.DeliveryReceiptCommited;
        }
        BoxupDetailDO boxupDetailDO=boxupDetailMapper.itemByBarcode(materialsDevanningParam.getBarcode(),deliveryReceiptDO.getId());
        if(boxupDetailDO==null){
            return ErrorCode.WarehouseBarcodeNotFound;
        }
        BoxUpDeliveryNoteVO boxUpDeliveryNoteVO=new BoxUpDeliveryNoteVO();
        switch (deliveryReceiptDO.getBillType()){
            case"XGFT":
                boxUpDeliveryNoteVO=deliveryNoteDetailMapper.itemByNoAndMaterialsNo(materialsDevanningParam.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                if(boxUpDeliveryNoteVO==null){
                    return ErrorCode.BarcodeNotFound;
                }
                DeliveryNoteDetailDO deliveryNoteDetailDO=new DeliveryNoteDetailDO();
                deliveryNoteDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                deliveryNoteDetailDO.setId(boxUpDeliveryNoteVO.getId());
                deliveryNoteDetailMapper.update(deliveryNoteDetailDO);
                break;
            case "XGSC":
                boxUpDeliveryNoteVO=threeGuaranteesOutDetailMapper.itemByNoAndMaterialsNo(materialsDevanningParam.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                if(boxUpDeliveryNoteVO==null){
                    return ErrorCode.BarcodeNotFound;
                }
                ThreeGuaranteesOutDetailDO threeGuaranteesOutDetailDO=new ThreeGuaranteesOutDetailDO();
                threeGuaranteesOutDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                threeGuaranteesOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                threeGuaranteesOutDetailMapper.update(threeGuaranteesOutDetailDO);
                break;
            case "XGQD":boxUpDeliveryNoteVO=regionAllotDetailMapper.itemByNoAndMaterialsNo(materialsDevanningParam.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                if(boxUpDeliveryNoteVO==null){
                    return ErrorCode.BarcodeNotFound;
                }
                RegionAllotDetailDO regionAllotDetailDO=new RegionAllotDetailDO();
                regionAllotDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                regionAllotDetailDO.setId(boxUpDeliveryNoteVO.getId());
                regionAllotDetailMapper.updateByPrimaryKeySelective(regionAllotDetailDO);
                break;
            case "XGFC":boxUpDeliveryNoteVO=abnormalOutDetailMapper.itemByNoAndMaterialsNo(materialsDevanningParam.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                if(boxUpDeliveryNoteVO==null){
                    return ErrorCode.BarcodeNotFound;
                }
                AbnormalOutDetailDO abnormalOutDetailDO=new AbnormalOutDetailDO();
                abnormalOutDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                abnormalOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                abnormalOutDetailMapper.updateByPrimaryKeySelective(abnormalOutDetailDO);
                break;
        }
        boxupDetailMapper.deleteByBarcode(boxupDetailDO.getBarcode(),boxupDetailDO.getBoxupId());
        return  ErrorCode.Success;
    }


    @Transactional(rollbackFor = Exception.class)
    public ErrorCode boxDevanning(String boxId){
        BoxupMainDO boxupMainDO=boxupMainMapper.item(boxId);
        if (boxupMainDO == null) {
            return ErrorCode.DeliveryReceiptInfoNotExists;
        }
        DeliveryReceiptDO deliveryReceiptDO=deliveryReceiptMapper.item(boxupMainDO.getDeliveryReceiptId());
        if (deliveryReceiptDO == null) {
            return ErrorCode.DeliveryReceiptInfoNotExists;
        }
        if(!deliveryReceiptDO.getDeliveryStatus().equals(DeliveryReceiptEnum.DeliveryStatus.UnDelivery.toString())){
            return ErrorCode.DeliveryReceiptCommited;
        }
        List<BoxupDetailDO> boxupDetailDOS=boxupDetailMapper.detailList(boxupMainDO.getBoxupId());
        for (BoxupDetailDO boxupDetailDO: boxupDetailDOS
             ) {
            BoxUpDeliveryNoteVO boxUpDeliveryNoteVO=new BoxUpDeliveryNoteVO();
            switch (deliveryReceiptDO.getBillType()){
                case"XGFT":
                    boxUpDeliveryNoteVO=deliveryNoteDetailMapper.itemByNoAndMaterialsNo(deliveryReceiptDO.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                    if(boxUpDeliveryNoteVO==null){
                        return ErrorCode.BarcodeNotFound;
                    }
                    DeliveryNoteDetailDO deliveryNoteDetailDO=new DeliveryNoteDetailDO();
                    deliveryNoteDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                    deliveryNoteDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    deliveryNoteDetailMapper.update(deliveryNoteDetailDO);
                    break;
                case "XGSC":
                    boxUpDeliveryNoteVO=threeGuaranteesOutDetailMapper.itemByNoAndMaterialsNo(deliveryReceiptDO.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                    if(boxUpDeliveryNoteVO==null){
                        return ErrorCode.BarcodeNotFound;
                    }
                    ThreeGuaranteesOutDetailDO threeGuaranteesOutDetailDO=new ThreeGuaranteesOutDetailDO();
                    threeGuaranteesOutDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                    threeGuaranteesOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    threeGuaranteesOutDetailMapper.update(threeGuaranteesOutDetailDO);
                    break;
                case "XGQD":boxUpDeliveryNoteVO=regionAllotDetailMapper.itemByNoAndMaterialsNo(deliveryReceiptDO.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                    if(boxUpDeliveryNoteVO==null){
                        return ErrorCode.BarcodeNotFound;
                    }
                    RegionAllotDetailDO regionAllotDetailDO=new RegionAllotDetailDO();
                    regionAllotDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                    regionAllotDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    regionAllotDetailMapper.updateByPrimaryKeySelective(regionAllotDetailDO);
                    break;
                case "XGFC":boxUpDeliveryNoteVO=abnormalOutDetailMapper.itemByNoAndMaterialsNo(deliveryReceiptDO.getOrgId(),boxupDetailDO.getDeliveryNoteNo(),boxupDetailDO.getMaterialsNo());
                    if(boxUpDeliveryNoteVO==null){
                        return ErrorCode.BarcodeNotFound;
                    }
                    AbnormalOutDetailDO abnormalOutDetailDO=new AbnormalOutDetailDO();
                    abnormalOutDetailDO.setPackNumber(boxUpDeliveryNoteVO.getPackNumber().subtract(boxupDetailDO.getQty()));
                    abnormalOutDetailDO.setId(boxUpDeliveryNoteVO.getId());
                    abnormalOutDetailMapper.updateByPrimaryKeySelective(abnormalOutDetailDO);
                    break;
            }
        }
        DeliveryReceiptDetailDO deliveryReceiptDetailDO=deliveryReceiptDetailMapper.item(boxupMainDO.getDeliveryReceiptId(),boxupMainDO.getPackCode());
        if(deliveryReceiptDetailDO!=null){
            if(deliveryReceiptDetailDO.getDeliveryQty().compareTo(new BigDecimal("1"))==0){
                deliveryReceiptDetailMapper.deleteByCode(boxupMainDO.getDeliveryReceiptId(),boxupMainDO.getPackCode());
            }else {
                deliveryReceiptDetailDO.setDeliveryQty(deliveryReceiptDetailDO.getDeliveryQty().subtract(new BigDecimal("1")));
                if(deliveryReceiptDetailDO.getDeliveryWeight()!=null && boxupMainDO.getWeight()!=null){
                    BigDecimal wight=deliveryReceiptDetailDO.getDeliveryWeight().multiply(boxupMainDO.getWeight());
                    deliveryReceiptDetailDO.setDeliveryWeight(wight);
                }
                deliveryReceiptDetailMapper.update(deliveryReceiptDetailDO);
            }
        }
        boxupDetailMapper.deleteByBoxupId(boxupMainDO.getBoxupId());
        boxupMainMapper.deleteByPrimaryKey(boxupMainDO.getBoxupId());
        return ErrorCode.Success;
    }

    private BoxupMainDO makeBoxupMainDO(BoxupParam boxupParam,String userId,DeliveryReceiptDO deliveryReceiptDO) throws Exception
    {
        BoxupMainDO boxupMainDO = new BoxupMainDO();
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return null;
        }
        String boxupId = textResult.getValue();
        boxupMainDO.setBoxupId(boxupId);
        if (StringUtils.isNotEmpty(boxupParam.getBoxupNo())){//混合装箱
            boxupMainDO.setBoxupNo(boxupParam.getBoxupNo());
        }else{
            boxupMainDO.setBoxupNo(genDocumentService.getDocumentNo(BillDesc.Boxup));
        }
        boxupMainDO.setOrgId(boxupParam.getOrgId());
        boxupMainDO.setDeliveryReceiptId(deliveryReceiptDO.getId());
        boxupMainDO.setDeliveryReceiptNo(deliveryReceiptDO.getBillNo());
        boxupMainDO.setOwerId(userId);
        boxupMainDO.setPackCode(boxupParam.getPackCode());
        boxupMainDO.setPackDesc(boxupParam.getPackDesc());
        boxupMainDO.setDepotMode(boxupParam.getDepotMode());
        boxupMainDO.setRemark(boxupParam.getRemark());
        boxupMainDO.setCreateTime(new Date());
        boxupMainDO.setCreateId(userId);
        ActionResult userAuth = authClient.getUserDetail(userId);
        UserCacheDTO userInfo = (UserCacheDTO) userAuth.getValue();
        String userName="";
        if (userInfo != null) {
            userName=userInfo.getName();
        }
        boxupMainDO.setCreateName(userName);
        boxupMainDO.setIsDel(false);
        boxupMainDO.setWeight(boxupParam.getWeight());
        boxupMainDO.setBoxCode(boxupParam.getBoxCode());
        boxupMainDO.setLenghtNum(boxupParam.getLenghtNum());
        boxupMainDO.setHightNum(boxupParam.getHightNum());
        boxupMainDO.setWithNum(boxupParam.getWithNum());
        boxupMainDO.setRoughWeight(boxupParam.getRoughWeight());
        boxupMainDO.setPackageSpecId(boxupParam.getPackageSpecId());
        boxupMainDO.setTempLocationCode(boxupParam.getTempLocationCode());
        return boxupMainDO;
    }

    private BoxupDetailDO makeBoxupDetailDO(BoxupMainDO boxupMainDO,BoxupDetailParam boxupDetailParam,BoxUpDeliveryNoteVO boxUpDeliveryNoteVO)
    {
        BoxupDetailDO boxupDetailDO=new BoxupDetailDO();
        boxupDetailDO.setBoxupId(boxupMainDO.getBoxupId());
        boxupDetailDO.setBoxupNo(boxupMainDO.getBoxupNo());
        boxupDetailDO.setBarcode(boxupDetailParam.getBarcode());
        boxupDetailDO.setMaterialsNo(boxupDetailParam.getMateriatsNo());
        boxupDetailDO.setMaterialsDes(boxupDetailParam.getMateriatsDes());
        boxupDetailDO.setDeliveryNoteId(boxUpDeliveryNoteVO.getDeliveryNoteId());
        boxupDetailDO.setDeliveryNoteNo(boxUpDeliveryNoteVO.getDeliveryNoteNo());
        boxupDetailDO.setQty(boxupDetailParam.getQty());
        boxupDetailDO.setPurchaseUnitPrice(boxUpDeliveryNoteVO.getUnitPriceAfterAdjust());//采购价
        boxupDetailDO.setRemark(boxupDetailParam.getRemark());
        boxupDetailDO.setCreateTime(new Date());
        boxupDetailDO.setCreateId(boxupMainDO.getCreateId());
        boxupDetailDO.setCreateName(boxupMainDO.getCreateName());
        boxupDetailDO.setIsDel(false);
        return boxupDetailDO;
    }

    public List<BoxupMainVO> list(BoxupMainVO boxupMainVO){
        if (boxupMainVO.getDeliveryReceiptNo().startsWith(BillDesc.Boxup.getDesc())){//扫描
            boxupMainVO.setBoxupNo(boxupMainVO.getDeliveryReceiptNo());
            boxupMainVO.setDeliveryReceiptNo(null);
        }
        PageHelperPlus.orderBy("create_time desc");
        List<BoxupMainDO> boxupMainDOList=boxupMainMapper.list(boxupMainVO);
        List<BoxupMainVO> boxupMainVOList=new ArrayList<>();
        for (BoxupMainDO boxupMainDO: boxupMainDOList
             ) {
            BoxupMainVO boxupMainVO1=new BoxupMainVO();
            BeanUtils.copyProperties(boxupMainDO,boxupMainVO1);
            boxupMainVOList.add(boxupMainVO1);
        }
        return boxupMainVOList;
    }

    public List<BoxupDetailVO> detailList(String boxupId){
        List<BoxupDetailDO> boxupDetailDOS=boxupDetailMapper.detailList(boxupId);
        List<BoxupDetailVO> results=new ArrayList<>();
        for (BoxupDetailDO boxupDetailDO:boxupDetailDOS) {
            BoxupDetailVO boxupDetailVO=new BoxupDetailVO();
            BeanUtils.copyProperties(boxupDetailDO,boxupDetailVO);
            results.add(boxupDetailVO);
        }
        return results;
    }

    public ErrorCode computeTotal(String deliveryReceiptNo,BoxupIndexVO boxupIndexVO){
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(deliveryReceiptNo);
        if (deliveryReceiptDO == null) {
            return ErrorCode.DeliveryReceiptInfoNotExists;
        }
        if(deliveryReceiptDO.getCommitType().equals(1)){
            return ErrorCode.DeliveryReceiptCommited;
        }
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(deliveryReceiptDO.getId());
        if (deliveryReceiptLinkDOList == null || deliveryReceiptLinkDOList.size() <= 0) {
            return ErrorCode.DeliveryReceiptNDeliveryNote;
        }
        BoxupMaterialsQuery boxupMaterialsQuery=new BoxupMaterialsQuery();
        boxupMaterialsQuery.setDeliveryReceiptLinkDOList(deliveryReceiptLinkDOList);
        DeliveryNoteDetailDO deliveryNoteDetailDO= deliveryNoteDetailMapper.computeTotal(boxupMaterialsQuery);
        if(deliveryNoteDetailDO==null){
            return ErrorCode.Failure;
        }
        boxupIndexVO.setBeenPackNumber(deliveryNoteDetailDO.getPackNumber());
        boxupIndexVO.setNotPackNumber(deliveryNoteDetailDO.getQty().subtract(boxupIndexVO.getBeenPackNumber()));
        return ErrorCode.Success;
    }

    public List<BoxupDetailVO> notPackList(String deliveryReceiptNo){
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(deliveryReceiptNo);
        if (deliveryReceiptDO == null) {
            return new ArrayList<>();
        }
        if(deliveryReceiptDO.getCommitType().equals(1)){
            return new ArrayList<>();
        }
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(deliveryReceiptDO.getId());
        if (deliveryReceiptLinkDOList == null || deliveryReceiptLinkDOList.size() <= 0) {
            return new ArrayList<>();
        }
        BoxupMaterialsQuery boxupMaterialsQuery=new BoxupMaterialsQuery();
        boxupMaterialsQuery.setDeliveryReceiptLinkDOList(deliveryReceiptLinkDOList);
        boxupMaterialsQuery.setBillId(deliveryReceiptDO.getId());
        List<BoxupDetailVO> listVO =new ArrayList<>();
        switch (deliveryReceiptDO.getBillType()){
            case "XGFT":
                listVO=deliveryNoteDetailMapper.notPackList(boxupMaterialsQuery);
                break;
            case "XGSC":
                listVO=threeGuaranteesOutDetailMapper.notPackList(boxupMaterialsQuery);
                break;
            case "XGQD":
                listVO=regionAllotDetailMapper.notPackList(boxupMaterialsQuery);
                break;
            case "XGFC":
                listVO=abnormalOutDetailMapper.notPackList(boxupMaterialsQuery);
                break;
        }
        return listVO;
    }
    public List<BoxupDetailVO> beenPackList(String deliveryReceiptNo){
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(deliveryReceiptNo);
        if (deliveryReceiptDO == null) {
            return new ArrayList<>();
        }
//        if(deliveryReceiptDO.getCommitType().equals(1)){
//            return new ArrayList<>();
//        }
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(deliveryReceiptDO.getId());
        if (deliveryReceiptLinkDOList == null || deliveryReceiptLinkDOList.size() <= 0) {
            return new ArrayList<>();
        }
        List<BoxupDetailVO> listVO=new ArrayList<>();
        BoxupMaterialsQuery boxupMaterialsQuery=new BoxupMaterialsQuery();
        boxupMaterialsQuery.setDeliveryReceiptLinkDOList(deliveryReceiptLinkDOList);
        boxupMaterialsQuery.setBillId(deliveryReceiptDO.getId());
        List<BoxupDetailDO> doList=boxupDetailMapper.beenPackList(boxupMaterialsQuery);
        for (BoxupDetailDO boxupDetailDO: doList
             ) {
            BoxupDetailVO boxupDetailVO=new BoxupDetailVO();
            BeanUtils.copyProperties(boxupDetailDO,boxupDetailVO);
            listVO.add(boxupDetailVO);
        }
        return listVO;
    }

    public ErrorCode update(BoxupMainVO boxupMainVO,String userId,String userName,String orgId){
//        BoxupMainDO boxupMainDO=boxupMainMapper.item(boxupMainVO.getBoxupId());
//        if(boxupMainDO==null){
//            return  ErrorCode.Failure;
//        }
        BoxupMainDO boxupMainDO = new BoxupMainDO();
        boxupMainDO.setBoxupNo(boxupMainVO.getBoxupNo());
        boxupMainDO.setWeight(boxupMainVO.getWeight());
        boxupMainDO.setRoughWeight(boxupMainVO.getRoughWeight());
        boxupMainDO.setWithNum(boxupMainVO.getWithNum());
        boxupMainDO.setHightNum(boxupMainVO.getHightNum());
        boxupMainDO.setLenghtNum(boxupMainVO.getLenghtNum());
        boxupMainDO.setBoxCode(boxupMainVO.getBoxCode());
        boxupMainDO.setTempLocationCode(boxupMainVO.getTempLocationCode());//暂存储位
        return boxupMainMapper.updateByBoxupNo(boxupMainDO) > 0 ? ErrorCode.Success : ErrorCode.Failure;
    }

    public List<BoxupDetailDO> boxDetailAmount(String deliveryReceiptId){
        return boxupDetailMapper.boxDetailAmount(deliveryReceiptId);
    }

    public List<BoxupMainVO> listByDelivery(BoxupMainVO boxupMainVO){
        // 进出口对应的主机厂或者进出口自己可以选择箱型
        CompanyInfoDO companyInfoDO = companyInfoMapper.itemBySap(CompanyUtil.JCK_SAP_CODE);
        List<BoxupMainDO> boxupMainDOList;
        if (boxupMainVO.getOrgId().equals(companyInfoDO.getOrgId())){//进出口
            boxupMainDOList = boxupMainMapper.listByDelivery(boxupMainVO.getOrgId(),Lists.newArrayList());
        }else{//进出口供应商--主机厂
            //进出口对应全部dealerOrgId
            List<String> dealerList = companyDealerMapper.findDealerOrgIds(companyInfoDO.getOrgId());
            dealerList = CollectionUtils.isEmpty(dealerList) ? Lists.newArrayList() : dealerList;
            dealerList.add(companyInfoDO.getOrgId());
            List<String> noDupList = dealerList.stream().distinct().collect(Collectors.toList());
            boxupMainDOList = boxupMainMapper.listByDelivery(boxupMainVO.getOrgId(),noDupList);
        }

        return BeanUtil.do2bo4List(boxupMainDOList,BoxupMainVO.class);
    }

    /**
     * 进出口装箱详情导出
     * @param boxupId
     * @return
     */
    public PrintDeliveryReceiptVO item4Export(String boxupId) throws Exception {

        PrintDeliveryReceiptVO printDeliveryReceiptVO;
        BoxupMainDO mainDO = boxupMainMapper.item(boxupId);
        if (mainDO == null) {
            return null;
        }

        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.item(mainDO.getDeliveryReceiptId());
        String billNo = deliveryReceiptDO.getBillNo();

        //查询装箱实际占用的箱子编号
        String boxupNo = mainDO.getBoxupNo();
        String orgId = mainDO.getOrgId();

        //根据boxupNos查询全部交接单号
        BoxupMainVO boxupMainVO = new BoxupMainVO();
        boxupMainVO.setOrgId(orgId);
        boxupMainVO.setBoxupNo(boxupNo);
        List<BoxupMainDO> mainDOs = boxupMainMapper.list(boxupMainVO);

        //查询关联的交接单号
        List<String> billIds = mainDOs.stream().map(BoxupMainDO::getDeliveryReceiptId).distinct().collect(Collectors.toList());

        //查询关联的发货通知单
        List<DeliveryReceiptLinkDO> billDOList = deliveryReceiptLinkMapper.listAll(billIds);
        List<String> deliveryNoteIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(billDOList)){
            deliveryNoteIds = billDOList.stream().map(DeliveryReceiptLinkDO::getDeliveryNoteId).distinct().collect(Collectors.toList());
        }

        //查询发货通知单列表
        DeliveryNoteVO deliveryNoteVO = new DeliveryNoteVO();
        deliveryNoteVO.setIds(deliveryNoteIds);
        List<DeliveryNoteDO> deliveryNoteDOList = deliveryNoteMapper.list(deliveryNoteVO);
        Map<String, DeliveryNoteDO> deliveryNoteDOMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(deliveryNoteDOList)){
            deliveryNoteDOMap = deliveryNoteDOList.stream().collect(Collectors.toMap(DeliveryNoteDO::getId, Function.identity(),(k1, k2)->k2));
        }

        List<DeliveryNoteDetailDO> deliveryNoteDetailDOList = deliveryNoteDetailMapper.listByDeliveryNoteIds(deliveryNoteIds);
        Map<String,List<DeliveryNoteDetailDO>> detailDOMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(deliveryNoteDetailDOList)){
            detailDOMap = deliveryNoteDetailDOList.stream().collect(Collectors.groupingBy(DeliveryNoteDetailDO::getMaterialsNo));
        }

        //装箱详情
        List<BoxupDetailDO> materialsList = boxupDetailMapper.listByBoxupNos(Lists.newArrayList(boxupNo), deliveryNoteIds);
        if (CollectionUtils.isEmpty(materialsList)){
            throw new Exception("装箱零件详情不能为空");
        }

        Map<String, PubMaterialsDO> pubMaterialsDOMap = new HashMap<>();
        List<String> materialsNos = materialsList.stream().map(BoxupDetailDO::getMaterialsNo).distinct().collect(Collectors.toList());
        List<PubMaterialsDO> pubMaterialsDOList = pubMaterialsMapper.selectByMaterialsNos(materialsNos);
        if (CollectionUtils.isNotEmpty(pubMaterialsDOList)){
            pubMaterialsDOMap = pubMaterialsDOList.stream().collect(Collectors.toMap(PubMaterialsDO::getMaterialsNo,Function.identity(),(k1,k2)->k2));
        }

        printDeliveryReceiptVO = new PrintDeliveryReceiptVO();
        BeanUtils.copyProperties(mainDO, printDeliveryReceiptVO);
        printDeliveryReceiptVO.setBillNo(billNo);//交接单号
        printDeliveryReceiptVO.setCheckerName(deliveryReceiptDO.getCheckerName());//验箱人
        printDeliveryReceiptVO.setBoxNo(1);//箱号

        List<PrintDeliveryReceiptDetailVO> detailVOList = Lists.newArrayList();
        PrintDeliveryReceiptDetailVO printDeliveryReceiptDetailVO;
        for (BoxupDetailDO boxupDetailDO : materialsList){
            String materialsNo = boxupDetailDO.getMaterialsNo();
            printDeliveryReceiptDetailVO = new PrintDeliveryReceiptDetailVO();
            BeanUtils.copyProperties(boxupDetailDO,printDeliveryReceiptDetailVO);
            if (billNo.startsWith("XGJK")){//进出口运单
                BarcodeManageDO barcodeDO = barcodeManageMapper.item(boxupDetailDO.getBarcode(), mainDO.getOrgId());
                if (StringUtils.isEmpty(barcodeDO.getPurchaseContractNo())){
                    throw new Exception("零件【"+ materialsNo +"】--条码【"+boxupDetailDO.getBarcode()+"】对应批次号（采购订单号）不能为空");
                }
                printDeliveryReceiptDetailVO.setPurchaseContractNo(barcodeDO.getPurchaseContractNo());//采购合同编号
                printDeliveryReceiptDetailVO.setMachineModel(barcodeDO.getMachineModel());//机型
                if (StringUtils.isEmpty(printDeliveryReceiptVO.getCountry())){
                    printDeliveryReceiptVO.setCountry(barcodeDO.getCountry());//国家
                }

                if (detailDOMap.containsKey(materialsNo)) {
                    Optional<DeliveryNoteDetailDO> noteDetailDOOptional = detailDOMap.get(materialsNo).stream().filter(item -> StringUtils.isNotBlank(item.getOriginalMaterialsNo())).findFirst();
                    if (noteDetailDOOptional.isPresent()) {
                        printDeliveryReceiptDetailVO.setOriginalMaterialsNo(noteDetailDOOptional.get().getOriginalMaterialsNo());
                    }
                }

            }else{//进出口发运交接单
                if (deliveryNoteDOMap.containsKey(boxupDetailDO.getDeliveryNoteId())){
                    DeliveryNoteDO deliveryNoteDO = deliveryNoteDOMap.get(boxupDetailDO.getDeliveryNoteId());
                    if(StringUtils.isEmpty(deliveryNoteDO.getPurchaseContractNo())){
                        throw new Exception("零件【"+ materialsNo +"】对应批次号（采购订单号）不能为空");
                    }


                    printDeliveryReceiptDetailVO.setPurchaseContractNo(deliveryNoteDO.getPurchaseContractNo());//采购合同编号
                    if (StringUtils.isEmpty(printDeliveryReceiptVO.getCountry())){
                        printDeliveryReceiptVO.setCountry(deliveryNoteDO.getCountry());//国家
                    }

                    //机型 原零件号
                    if (detailDOMap.containsKey(materialsNo)){
                        //过滤同一发货通知单
                        List<DeliveryNoteDetailDO> noteDetailDOS = detailDOMap.get(materialsNo).stream()
                                .filter(n->n.getDeliveryNoteNo().equals(deliveryNoteDO.getId())).collect(Collectors.toList());
                        printDeliveryReceiptDetailVO.setMachineModel(noteDetailDOS.get(0).getMachineModel());
                        Optional<DeliveryNoteDetailDO> noteDetailDOOptional = detailDOMap.get(materialsNo).stream().filter(item-> StringUtils.isNotBlank(item.getOriginalMaterialsNo())).findFirst();
                        if (noteDetailDOOptional.isPresent()) {
                            printDeliveryReceiptDetailVO.setOriginalMaterialsNo(noteDetailDOOptional.get().getOriginalMaterialsNo());
                        }
                    }
                }
            }
            printDeliveryReceiptDetailVO.setDeliveryNoteNo(boxupDetailDO.getDeliveryNoteNo());//发货通知单号
            printDeliveryReceiptDetailVO.setMaterialsDesCN(boxupDetailDO.getMaterialsDes());
            //英文描述
            if (pubMaterialsDOMap.containsKey(materialsNo)){
                printDeliveryReceiptDetailVO.setMaterialsDesEN(pubMaterialsDOMap.get(materialsNo).getMaterialsDesEn());
            }
            detailVOList.add(printDeliveryReceiptDetailVO);
        }

        //合并相同采购合同号，零件号
        Map<String,Map<String,List<PrintDeliveryReceiptDetailVO>>> groupMap = detailVOList.stream().collect(
                Collectors.groupingBy(PrintDeliveryReceiptDetailVO::getPurchaseContractNo,
                        Collectors.groupingBy(PrintDeliveryReceiptDetailVO::getMaterialsNo)));

        List<PrintDeliveryReceiptDetailVO> materialsNOList = Lists.newArrayList();
        for (Map.Entry<String,Map<String,List<PrintDeliveryReceiptDetailVO>>> groupEntry : groupMap.entrySet()){
            for (Map.Entry<String,List<PrintDeliveryReceiptDetailVO>> entry : groupEntry.getValue().entrySet()){
                printDeliveryReceiptDetailVO = new PrintDeliveryReceiptDetailVO();
                printDeliveryReceiptDetailVO.setPurchaseContractNo(groupEntry.getKey());

                printDeliveryReceiptDetailVO.setMaterialsNo(entry.getKey());
                List<PrintDeliveryReceiptDetailVO> deliveryReceiptDetailVOS =  entry.getValue();
                BigDecimal totalAmount = deliveryReceiptDetailVOS.stream().map(PrintDeliveryReceiptDetailVO::getQty)
                        .reduce(BigDecimal.ZERO,BigDecimal::add);
                printDeliveryReceiptDetailVO.setQty(totalAmount);
                printDeliveryReceiptDetailVO.setMaterialsDesEN(deliveryReceiptDetailVOS.get(0).getMaterialsDesEN());
                printDeliveryReceiptDetailVO.setMaterialsDesCN(deliveryReceiptDetailVOS.get(0).getMaterialsDesCN());
                printDeliveryReceiptDetailVO.setMachineModel(deliveryReceiptDetailVOS.get(0).getMachineModel());
                printDeliveryReceiptDetailVO.setOriginalMaterialsNo(deliveryReceiptDetailVOS.get(0).getOriginalMaterialsNo());
                printDeliveryReceiptDetailVO.setDeliveryNoteNo(deliveryReceiptDetailVOS.get(0).getDeliveryNoteNo());
                materialsNOList.add(printDeliveryReceiptDetailVO);
            }
        }

        //编辑序号
        for (int i = 0; i < materialsNOList.size(); i++){
            materialsNOList.get(i).setIndex(i+1);
        }

        printDeliveryReceiptVO.setMaterialsList(materialsNOList);
        return printDeliveryReceiptVO;
    }
}
